//: Playground - noun: a place where people can play

import UIKit

//: # swfit 读书笔记

//: ## 枚举语法
print("_____________________枚举语法_____________________________")
enum CompassPoint {
    case north
    case south
    case east
    case west
}

var directionToHead = CompassPoint.west
directionToHead = .east

//: ## 使用 Switch 语句匹配枚举值
print("_____________________使用 Switch 语句匹配枚举值_____________________________")

directionToHead = .north


switch directionToHead {
case .north:
    print("default - north")
default:
    print("default - other")
}

switch directionToHead {
case .north:
    print("all - north")
case .south:
    print("all - south")
case .east:
    print("all - east")
case .west:
    print("all - west")
}

//: ## 关联值
print("_____________________关联值_____________________________")
enum Barcode {
    case upc(Int, Int, Int, Int)
    case qrCode(String)
}

var productBarcode = Barcode.upc(8, 85909, 51226, 3)

productBarcode = .qrCode("ABCDEFGHIJKLMNOP")
//: 联值可以被提取出来作为 switch 语句的一部分。你可以在switch的 case 分支代码中提取每个关联值作为一个常量（用let前缀）或者作为一个变量（用var前缀）来使用
switch productBarcode {
case .upc(let numberSystem, let manufacturer, let product, let check):
    print("UPC: \(numberSystem), \(manufacturer), \(product), \(check).")
case .qrCode(let productCode):
    print("QR code: \(productCode).")
}

//: 如果一个枚举成员的所有关联值都被提取为常量，或者都被提取为变量，为了简洁，你可以只在成员名称前标注一个let或者var：
switch productBarcode {
case let .upc(numberSystem, manufacturer, product, check):
    print("UPC: \(numberSystem), \(manufacturer), \(product), \(check).")
case let .qrCode(productCode):
    print("QR code: \(productCode).")
}


//: ## 原始值  原始值的类型必须相同。  原始值可以是字符串，字符，或者任意整型值或浮点型值。每个原始值在枚举声明中必须是唯一的,原始值为整数或者字符串类型的枚举时，不需要显式地为每一个枚举成员设置原始值，Swift 将会自动为你赋值

print("_____________________原始值_____________________________")
enum ASCIIControlCharacter: Character {
    case tab = "\t"
    case lineFeed = "\n"
    case carriageReturn = "\r"
}
//: ### 当使用整数作为原始值时，隐式赋值的值依次递增1。如果第一个枚举成员没有设置原始值，其原始值将为0
//: ### venus 是 2
enum Planet:Int {
    case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune
}

//: ### FamilyName.FamilyNameOne 的原始值是 FamilyNameOne
enum FamilyName:String{
    case FamilyNameOne, FamilyNameTwo,FamilyNameThree,FamilyName
}

print("FamilyName.FamilyNameOne.rawValue - \(FamilyName.FamilyNameOne.rawValue)")

//: ### 原始值初始化枚举实例
print("_____________________原始值初始化枚举实例_____________________________")
var currentFN = FamilyName (rawValue: "FamilyNameTwo")!
print("currentFN + \(String(describing: currentFN))）")

//: ##  递归枚举  就是枚举可以引用其他枚举的值
//: ### 通过关键字 indirect 表示成员是否可以递归 (他可以添加到 某个 case 前面，也可以添加到 enum 关键字前面代表所有 case 都是递归的)
 print("_____________________递归枚举_____________________________")
indirect enum ArithmeticExpression{
    case number(Int)
    case addition(ArithmeticExpression,ArithmeticExpression)
    case multiplication(ArithmeticExpression,ArithmeticExpression)
}

//: ### 实现 （5+4）* 2
let five = ArithmeticExpression.number(5)
let four = ArithmeticExpression.number(4)
let sum = ArithmeticExpression.addition(five, four)
let product = ArithmeticExpression.multiplication(sum, ArithmeticExpression.number(2))
print("product - \(product)")

//: ### 操作具有递归性质的数据结构，使用递归函数是一种直截了当的方式
func evaluate(_ expression:ArithmeticExpression)-> Int{
    switch expression {
    case let .number(value):
        return value
    case let addition(left,right)
        return evaluate(left) + evaluate(right)
    case let multiplication(left,right)
        return  evaluate(left) * evaluate(right)
    }
}
